using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Xml;
using ZoneFiveSoftware.Common.Data.Fitness;
using ZoneFiveSoftware.Common.Visuals;

namespace STCommon.View
{
    public class TreeListOptionsSerializer
    {
        public TreeListOptionsSerializer()
        {
        }

        public void LoadFromSettings(XmlNode settingsNode)
        {
            SettingsXMLNode = settingsNode;

            if (SettingsXMLNode != null &&
                m_ManagedTreeList != null)
            {
                LoadFromSettingsInternal();
            }
        }

        public void SaveToSettings(XmlDocument xmlDoc, XmlNode treeListNode, String childNodeName)
        {
            if (m_ManagedTreeList != null &&
                xmlDoc != null && treeListNode != null &&
                !String.IsNullOrEmpty(childNodeName))
            {
                XmlNode masterNode = xmlDoc.CreateElement(childNodeName);
                treeListNode.AppendChild(masterNode);

                // Make sure we use the last settings
                if (SettingsXMLNode != null)
                {
                    LoadFromSettingsInternal();
                }

                foreach (TreeList.Column column in m_ManagedTreeList.Columns)
                {
                    SaveSingleNode(column, xmlDoc, masterNode);
                }

                // Fixed column
                XmlNode dataNode;
                dataNode = xmlDoc.CreateElement(FixedColumnCountSettingNodeName);
                masterNode.AppendChild(dataNode);
                dataNode.AppendChild(xmlDoc.CreateTextNode(m_ManagedTreeList.NumLockedColumns.ToString()));

                // Sorted column
                String sortedColumnId = String.Empty;
                bool sortAscending = true;

                m_ManagedTreeList.GetSortIndicator(out sortedColumnId, out sortAscending);

                if (!String.IsNullOrEmpty(sortedColumnId) &&
                    FindColumnById(sortedColumnId) != null)
                {
                    XmlNode subChildNode;

                    dataNode = xmlDoc.CreateElement(SortedColumnSettingNodeName);
                    masterNode.AppendChild(dataNode);

                    // Column id
                    subChildNode = xmlDoc.CreateElement(ColumnIdSettingNodeName);
                    dataNode.AppendChild(subChildNode);
                    subChildNode.AppendChild(xmlDoc.CreateTextNode(sortedColumnId));

                    // Sorting order
                    subChildNode = xmlDoc.CreateElement(SortedAscendingSettingNodeName);
                    dataNode.AppendChild(subChildNode);
                    subChildNode.AppendChild(xmlDoc.CreateTextNode(sortAscending.ToString()));
                }
            }
        }

        private void LoadFromSettingsInternal()
        {
            if (SettingsXMLNode != null && m_ManagedTreeList != null)
            {
                foreach (XmlNode child in SettingsXMLNode)
                {
                    if (child.Name == TreeListColumnInfoSettingNodeName)
                    {
                        TreeList.Column column = null;
                        int width = 0;
                        bool visible = true;
                        bool columnVisibilityRead = false;
                        bool columnWidthRead = false;

                        foreach (XmlNode attribute in child)
                        {
                            // Value member
                            if (attribute.Name == ColumnIdSettingNodeName && attribute.ChildNodes.Count == 1)
                            {
                                // FindColumn because we don't want to recreate it
                                column = FindColumnById(attribute.FirstChild.Value);
                            }
                            // Width
                            else if (attribute.Name == ColumnWidthSettingNodeName && attribute.ChildNodes.Count == 1)
                            {
                                width = int.Parse(attribute.FirstChild.Value);
                                columnWidthRead = true;
                            }
                            // Visible
                            else if (attribute.Name == ColumnVisibilitySettingNodeName && attribute.ChildNodes.Count == 1)
                            {
                                visible = bool.Parse(attribute.FirstChild.Value);
                                columnVisibilityRead = true;
                            }
                        }

                        // Update our column with the loaded data
                        if (column != null)
                        {
                            if (columnWidthRead)
                            {
                                column.Width = width;
                            }

                            if (columnVisibilityRead)
                            {
                                column.Visible = visible;
                            }
                        }
                    }
                    else if (child.Name == FixedColumnCountSettingNodeName && child.ChildNodes.Count == 1)
                    {
                        // Fixed column count
                        m_ManagedTreeList.NumLockedColumns = int.Parse(child.FirstChild.Value);
                    }
                    else if (child.Name == SortedColumnSettingNodeName && child.ChildNodes.Count == 2)
                    {
                        String sortedId = String.Empty;
                        bool sortAscending = true;
                        bool sortRead = false;

                        foreach (XmlNode subChild in child.ChildNodes)
                        {
                            if (subChild.Name == ColumnIdSettingNodeName && subChild.ChildNodes.Count == 1)
                            {
                                sortedId = subChild.FirstChild.Value;
                            }
                            else if (subChild.Name == SortedAscendingSettingNodeName && subChild.ChildNodes.Count == 1)
                            {
                                sortAscending = bool.Parse(subChild.FirstChild.Value);
                                sortRead = true;
                            }
                        }

                        if (!String.IsNullOrEmpty(sortedId) &&
                            FindColumnById(sortedId) != null &&
                            sortRead)
                        {
                            m_ManagedTreeList.SetSortIndicator(sortedId, sortAscending);
                        }
                    }
                }

                SettingsXMLNode = null;
            }
        }

        private void SaveSingleNode(TreeList.Column column, XmlDocument xmlDoc, XmlNode masterNode)
        {
            XmlNode child, dataNode;

            child = xmlDoc.CreateElement(TreeListColumnInfoSettingNodeName);
            masterNode.AppendChild(child);

            // Id
            dataNode = xmlDoc.CreateElement(ColumnIdSettingNodeName);
            child.AppendChild(dataNode);
            dataNode.AppendChild(xmlDoc.CreateTextNode(column.Id.ToString()));

            // Width
            dataNode = xmlDoc.CreateElement(ColumnWidthSettingNodeName);
            child.AppendChild(dataNode);
            dataNode.AppendChild(xmlDoc.CreateTextNode(column.Width.ToString()));

            // Visible
            dataNode = xmlDoc.CreateElement(ColumnVisibilitySettingNodeName);
            child.AppendChild(dataNode);
            dataNode.AppendChild(xmlDoc.CreateTextNode(column.Visible.ToString()));
        }

        private TreeList.Column FindColumnById(String columnId)
        {
            if (m_ManagedTreeList != null)
            {
                foreach(TreeList.Column currentColumn in m_ManagedTreeList.Columns)
                {
                    if(currentColumn.Id.Equals(columnId))
                    {
                        return currentColumn;
                    }
                }
            }

            return null;
        }

        private XmlNode SettingsXMLNode
        {
            get { return m_SettingsXmlNode; }
            set { m_SettingsXmlNode = value; }
        }

        public ExtendedTreeList TreeList
        {
            get { return m_ManagedTreeList; }
            set
            {
                m_ManagedTreeList = value;

                LoadFromSettingsInternal();
            }
        }

        // Tree list attributes
        private const String TreeListColumnInfoSettingNodeName = "TreeListColumnInfo";
        private const String FixedColumnCountSettingNodeName = "FixedColumnCount";
        private const String SortedColumnSettingNodeName = "SortedColumn";
        private const String SortedAscendingSettingNodeName = "SortedAscending";

        // Column attributes
        private static readonly String ColumnIdSettingNodeName = "ColumnId";
        private static readonly String ColumnWidthSettingNodeName = "ColumnWidth";
        private static readonly String ColumnVisibilitySettingNodeName = "ColumnVisible";

        private ExtendedTreeList m_ManagedTreeList = null;
        private XmlNode m_SettingsXmlNode = null;
    }
}
